home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Hot Mix 17
/
Hot Mix 17.iso
/
HM17_SGI
/
research
/
examples
/
demo
/
demosrc
/
d_globe.pro
< prev
next >
Wrap
Text File
|
1997-07-08
|
29KB
|
837 lines
; $Id: d_globe.pro,v 1.19 1997/04/18 17:51:14 alan Exp $
;
; Copyright (c) 1997, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
;
;+
; FILE:
; d_globe.pro
;
; CALLING SEQUENCE: d_globe
;
; PURPOSE:
; Demonstrates texture mapping, model rotations, and indexed color
; table stretching with IDL's object graphics system.
; (object graphics only)
;
; MAJOR TOPICS: Indexed colors & Color palettes, Texture Mapping, Trackball.
;
; CATEGORY:
; IDL 5.0
;
; INTERNAL FUNCTIONS and PROCEDURES:
; pro globergbstretch - stretches RGB vectors into new RGB vectors
; pro globestretch_event - event handler for stretching colors
; pro d_globe_event - event handler
; pro d_globecleanup - cleanup routine
; pro globereadimages - inputs and scales images
; function globemakeobjects - creates the object hierarchy
; pro d_globe - Main procedure
;
; EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
; pro trackball__define.pro - Create trackball object.
; pro orb__define.pro - Create an orb object
; pro gettips - Get the tips text structure..
; pro widtips - Create the widget text for tips.
; globe.txt - "About" file
; globe.tip - "Tips" file
; worldelv.dat - global topography image dataset
; worldtmp.sav - global temperature image dataset & RGB's
;
; REFERENCE: IDL Reference Guide, IDL User's Guide
;
;
; NAMED STRUCTURES:
; none.
;
; COMMON BLOCS:
; none.
;
; MODIFICATION HISTORY: Written by: MCR, RSI, February 97
;-
;----------------------------------------------------------------------
; PURPOSE This routine stretches old RGB vectors
; (oldReds, oldGreens, oldBlues) based on
; low and high stretch values (low, high)
; and passes back new RGB vectors
; (newReds, newGreens, newBlues). This routine
; is based on the Stretch.pro routine found within
; the IDL distribution. One may stretch color vectors
; of any length.
;
pro GlobeRGBStretch, $
oldReds, oldGreens, oldBlues, $ ;IN: Input RGB Vectors
newReds, newGreens, newBlues, $ ;OUT: Output RGB Vectors
LOW=low, HIGH=high ;IN: (opt) stretch indices
WIDGET_CONTROL, HOURGLASS = 1
nColors=N_ELEMENTS(oldReds)
if (not KEYWORD_SET(low)) then $
low=0L
if (not KEYWORD_SET(high)) then $
high=nColors-1L
if (high-low ne 0) then begin ;if low and high are not equal
slope=FLOAT(nColors-1)/(high-low)
intercept=-slope*low
endif else begin ;if low and high are equal
slope=0b & intercept=low
endelse
sub=LONG(FINDGEN(nColors)*slope+intercept)
newReds=oldReds[sub]
newGreens=oldGreens[sub]
newBlues=oldBlues[sub]
WIDGET_CONTROL, HOURGLASS = 0
end
;----------------------------------------------------------------------
;
; PURPOSE ; This is a secondary event handler routine
; used in the Globe demo. This routine is used
; to stretch the coor indices of the respective
; datasets. One can either stretch the color vectors
; for the temperature data or stretch the colors
; vectors for the topography data.
;
pro GlobeStretch_Event, $
sEvent
WIDGET_CONTROL, HOURGLASS = 1
WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
WIDGET_CONTROL, sEvent.id, GET_UVALUE=wsliders
; Build subscripts of RGB vectors associated
; with the images.
;
elev=LINDGEN(sState.nColors/2)
temps=LINDGEN(sState.nColors/2)+sState.nColors/2
; Check that minimim sliders do not exceed
; the maximum sliders and
; that maximum sliders are not less than minimum sliders
; and make adjustments as needed.
;
WIDGET_CONTROL, wsliders[0], GET_VALUE=sliderValue0
WIDGET_CONTROL, wsliders[1], GET_VALUE=sliderValue1
WIDGET_CONTROL, wsliders[2], GET_VALUE=sliderValue2
WIDGET_CONTROL, wsliders[3], GET_VALUE=sliderValue3
if (sEvent.id EQ wsliders[0] and sliderValue0 gt sliderValue1) then begin
WIDGET_CONTROL, wsliders[0], SET_VALUE=sliderValue1
sliderValue0 = sliderValue1
endif
if (sEvent.id EQ wsliders[1] and sliderValue0 gt sliderValue1) then begin
WIDGET_CONTROL, wsliders[1], SET_VALUE=sliderValue0
slidervalue1 = sliderValue0
endif
if (sEvent.id EQ wsliders[2] and sliderValue2 gt sliderValue3) then begin
WIDGET_CONTROL, wsliders[2], SET_VALUE=sliderValue3
sliderValue2 = sliderValue3
endif
if (sEvent.id EQ wsliders[3] and sliderValue2 gt sliderValue3) then begin
WIDGET_CONTROL, wsliders[3], SET_VALUE=sliderValue2
sliderValue3 = sliderValue2
endif
; Stretch the original color vectors and then save the stretched
; vectors into the color palette. Note, the original colors are
; always stretch so that information is not lost by stretching
; vectors that have already been stretched.
; (both datasets individually)
;
GlobeRGBStretch, sState.reds[elev], sState.greens[elev], $
sState.blues[elev], newReds1, newGreens1, newBlues1, $
LOW=sliderValue0, HIGH=sliderValue1
GlobeRGBStretch, sState.reds[temps], sState.greens[temps], $
sState.blues[temps], newReds2, newGreens2, newBlues2, $
LOW=sliderValue2-sState.ncolors/2, $
HIGH=sliderValue3-sState.ncolors/2
reds=[newReds1, newReds2]
greens=[newGreens1, newGreens2]
blues=[newBlues1, newBlues2]
sState.oPalette->SetProperty, RED_VALUES=reds, $
GREEN_VALUES=greens, BLUE_VALUES=blues
sState.oWindow->Draw, sState.oView
WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
WIDGET_CONTROL, HOURGLASS = 0
end
;----------------------------------------------------------------------
;
; PURPOSE This is the main event handler routine
; use in the Globe demo.
;
pro d_Globe_Event, $
sEvent
; Quit this application using the close box.
;
if (TAG_NAMES(sEvent, /STRUCTURE_NAME) EQ $
'WIDGET_KILL_REQUEST') then begin
WIDGET_CONTROL, sEvent.top, /DESTROY
RETURN
endif
WIDGET_CONTROL, sEvent.id, GET_UVALUE=uvalue
case uvalue of
; Handle radio button events .
; Here Handle event for showing over continents.
;
'RADIO1': begin
WIDGET_CONTROL, HOURGLASS=1
WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
WIDGET_CONTROL, sState.wGroup2, GET_VALUE=twin
if (sEvent.value EQ 0 AND twin EQ 0) then $
sState.oImage->SetProperty, DATA=*sState.pImageTemp
if (sEvent.value EQ 1 AND twin EQ 0) then $
sState.oImage->SetProperty, DATA=*sState.pImageTopoTemp
if (sEvent.value EQ 1 AND twin EQ 1) then $
sState.oImage->SetProperty, DATA=*sState.pImageTopo
if (sEvent.value EQ 0 AND twin EQ 1) then $
sState.oImage->SetProperty, DATA=*sState.pImageTempTopo
sState.oWindow->Draw, sState.oView
WIDGET_CONTROL, HOURGLASS=0
WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
end
; Reset perspective.
;
'RESET': begin
WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
sState.oModelRotate->SetProperty, $
TRANSFORM=sState.resetTransform
sState.oWindow->Draw, sState.oView
WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
end
; Handle radio button events.
; Here Handle event for showing over oceans.
;
'RADIO2': begin
WIDGET_CONTROL, HOURGLASS=1
WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
WIDGET_CONTROL, sState.wGroup1, GET_VALUE=twin
if (sEvent.value EQ 0 AND twin EQ 0) then $
sState.oImage->SetProperty, DATA=*sState.pImageTemp
if (sEvent.value EQ 1 AND twin EQ 0) then $
sState.oImage->SetProperty, DATA=*sState.pImageTempTopo
if (sEvent.value EQ 1 AND twin EQ 1) then $
sState.oImage->SetProperty, DATA=*sState.pImageTopo
if (sEvent.value EQ 0 AND twin EQ 1) then $
sState.oImage->SetProperty, DATA=*sState.pImageTopoTemp
sState.oWindow->Draw, sState.oView
WIDGET_CONTROL, HOURGLASS=0
WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
end
; Handle trackball events here.
; still need to add trackball object
; and place in object hierarchy.
;
'DRAW': begin
WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
bHaveTransform=sState.oTrack->Update(sEvent, TRANSFORM=qmat)
if (bHaveTransform NE 0) then begin
sState.oModelRotate->GetProperty, TRANSFORM=trans
mtrans=trans # qmat
sState.oModelRotate->SetProperty, TRANSFORM=mtrans
endif
; Handle button press.
;
if (sEvent.type EQ 0) then $
WIDGET_CONTROL, sState.wDraw, DRAW_MOTION=1
if (sEvent.type EQ 2) then begin
if (bHaveTransform) then begin
sState.oWindow->SetProperty, QUALITY=0
sState.oWindow->Draw,sState.oView
endif
endif
; Handle button release.
;
if (sEvent.type EQ 1) then begin
sState.oWindow->SetProperty, QUALITY=2
WIDGET_CONTROL, sState.wDraw, DRAW_MOTION=0
sState.oWindow->Draw, sState.oView
endif
; Handle expose events.
;
if (sEvent.type EQ 4) then begin
sState.oWindow->Draw, sState.oView
endif
WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
end
; Quit this application.
;
'QUIT': begin
WIDGET_CONTROL, sEvent.top, /DESTROY
end
; Display the information file.
;
'ABOUT' : begin
if (XREGISTERED('XDisplayFile') NE 0) then RETURN
WIDGET_CONTROL, sEvent.top, GET_UVALUE=sState, /NO_COPY
XDISPLAYFILE, sState.fileNameAbout, $
WIDTH=55, HEIGHT=14, DONE_BUTTON='Done', $
TITLE='About the Globe Demo' , $
GROUP=sEvent.top
WIDGET_CONTROL, sEvent.top, SET_UVALUE=sState, /NO_COPY
end
; Handle all other events.
;
ELSE: ; Do nothing
endcase
end
;----------------------------------------------------------------------
;
; PURPOSE Cleanup everything associated with the
; Globe demo, including all objects and pointers.
; Restore the original color table.
;
pro d_GlobeCleanup, tlb
WIDGET_CONTROL, tlb, GET_UVALUE=sState, /NO_COPY
; Restore the previous color table.
;
TVLCT, sState.colorTable
; Destroy the top objects & attribute objects.
;
OBJ_DESTROY, sState.oView
OBJ_DESTROY, sState.oPalette
OBJ_DESTROY, sState.oTrack
OBJ_DESTROY, sState.oText
OBJ_DESTROY, sState.oFont
OBJ_DESTROY, sState.oContainer
; Free all pointers.
;
PTR_FREE, sState.pImageTempTopo
PTR_FREE, sState.pImageTopoTemp
PTR_FREE, sState.pImageTemp
PTR_FREE, sState.pImageTopo
; Map the group leader base if it exists.
;
if (WIDGET_INFO(sState.groupBase, /VALID_ID)) then $
WIDGET_CONTROL, sState.groupBase, /MAP
end
;----------------------------------------------------------------------
;
; PURPOSE Inputs the images used in the Globe demo.
; This procedure returns
; four pointers back to the caller.
; These pointers point to the given images.
;
pro GlobeReadImages, $
fileNameElev, $ ;IN: filename for elevation dataset
fileNameTemp, $ ;IN: filename for temperature dataset
nColors, $ ;IN: number of colors used to scale both images
pImageTemp, $ ;OUT: world temperatures
pImageTopo, $ ;OUT: world topography
pImageTempTopo, $ ;OUT: continental temperature and oceanic elevation
pImageTopoTemp, $ ;OUT: ocean temperature and continental elevation
reds, $ ;OUT: red color indices
greens, $ ;OUT: green color indices
blues ;OUT: blue color indices
; Innput DEM from IDL distribution ("worldelv.dat") and
; corresponding temperature dataset from
; a .SAV file ("worldtmp.sav").
;
OPENR, lun, fileNameElev, /GET_LUN
topo=BYTARR(360, 360)
READU, lun, topo
CLOSE, LUN
FREE_LUN, lun
temps=BYTARR(360, 360)
; Read the temperature image.
;
Read_Gif, fileNameTemp, Temps, Reds, Greens, Blues
; Build masks to divide the two datasets.
;
oceanMask=WHERE(topo lt 124)
landMask=WHERE(topo ge 124)
; Create DEM( Digital elevation Model) images.
; (Color Ranges: [0]-[nColors/2-1]).
;
topoOceanScaled=BYTSCL(topo, TOP=nColors/2-1, $
MIN=MIN(topo[oceanMask]), MAX=MAX(topo[oceanMask]))
topoLandScaled=BYTSCL(topo, TOP=nColors/2-1, $
MIN=MIN(topo[landMask]), MAX=MAX(topo[landMask]))
topoScaled=BYTSCL(topo, TOP=nColors/2-1)
; Create temperature images.
; (Color Ranges: [nColors/2]-[nColors-1]).
;
tempLandScaled=BYTSCL(temps, TOP=nColors/2-1, $
MIN=MIN(temps[landMask]), $
MAX=MAX(temps[landMask]))+BYTE(nColors/2)
tempOceanScaled=BYTSCL(temps, TOP=nColors/2-1, $
MIN=MIN(temps[oceanMask]), $
MAX=MAX(temps[oceanMask]))+BYTE(nColors/2)
tempScaled=BYTSCL(temps, TOP=nColors/2-1)+BYTE(nColors/2)
; Create pointers to two images that are created based on the
; respective topography and temperature scalings.
;
pImageTemp=PTR_NEW(tempScaled)
pImageTopo=PTR_NEW(topoScaled)
imageTempTopo=BYTARR(360, 360) ;temperatures over continents
imageTempTopo[landMask]=tempLandScaled[landMask]
imageTempTopo[oceanMask]=topoOceanScaled[oceanMask]
pImageTempTopo=PTR_NEW(imageTempTopo)
imageTopoTemp=BYTARR(360, 360) ;temperatures over oceans
imageTopoTemp[oceanMask]=tempOceanScaled[oceanMask]
imageTopoTemp[landMask]=topoLandScaled[landMask]
pImageTopoTemp=PTR_NEW(imageTopoTemp)
; Scale color vectors based on number of colors.
;
reds=CONGRID(reds, nColors)
greens=CONGRID(greens, nColors)
blues=CONGRID(blues, nColors)
end
;----------------------------------------------------------------------
;
; PURPOSE Creates the object hierarchy
;
function GlobeMakeObjects, $
reds, $ ;IN: red color lookups
greens, $ ;IN: green color lookups
blues, $ ;IN: blue color lookups
screenSize, $ ;IN: screensize dimensions
pImageTempTopo, $ ;IN: pointer to image
oWindow ;IN: window object
myView = [-1.0, -1.0, 2.0, 2.0]
; Create view object.
;
oView = OBJ_NEW('IDLgrView', PROJECTION=2, EYE=4.0, $
COLOR=[0,0,0], $
VIEW=[-1.0, -1.0, 2.0, 2.0], ZCLIP=[1.0, -1.0])
; Make the starting up text location centered.
;
textLocation = [myview[0]+0.5*myview[2], myview[1]+0.5*myview[3]]
; Create and display the PLEASE WAIT text.
;
oFont = OBJ_NEW('IDLgrFont', 'Helvetica', SIZE=20)
oText = OBJ_NEW('IDLgrText', $
'Starting up Please wait...', $
ALIGN=0.5, $
LOCATION=textLocation, $
COLOR=[255,255,0], FONT=oFont)
; Create model objects for translation, rotation, and scaling.
;
oModelTranslate=OBJ_NEW('IDLgrModel')
oModelRotate=OBJ_NEW('IDLgrModel')
oModelScale=OBJ_NEW('IDLgrModel')
oModelTranslate->Add, oModelRotate
oModelRotate->Add, oModelScale
; Show the starting up text.
;
oview->Add, oModelTranslate
oModelTranslate->Add, oText
owindow->Draw, oView
; Create color palette object.
;
oPalette=obj_new('IDLgrPalette', reds, greens, blues)
; Create trackball object.
;
oTrack=OBJ_NEW('trackball', $
[(screenSize[0]*.4)/2.0, (screenSize[0]*.4)/2.0], $
(screenSize[0]*.4)/2.0)
; Create image object and add to model hierarchy.
;
oImage=OBJ_NEW('IDLgrImage', *pImageTempTopo, HIDE=1, $
PALETTE=oPalette)
oModelRotate->Add, oImage
; Create orb object and add to model hierarchy.
;
oSphere=OBJ_NEW('orb', DENSITY=0.99, /TEX_COORDS, $
TEXTURE_MAP=oImage, COLOR=[255, 255, 255], RADIUS=0.90)
oModelRotate->Add, oSphere
; Add model hierarchy to view, rotate or whatever,
; draw view to window.
;
oModelRotate->Rotate, [1, 0, 0], -90
oModelRotate->GetProperty, TRANSFORM=resetTransform
oContainer = OBJ_NEW('IDLgrContainer')
oContainer->Add, oView
oContainer->Add, oTrack
RETURN, {oView:oView, $
oModelTranslate: oModelTranslate, $
oModelRotate: oModelRotate, $
oModelScale: oModelScale, $
oPalette: oPalette, $
oImage: oImage, $
oSphere: oSphere, $
oTrack: oTrack, $
oWindow: oWindow, $
oContainer: oContainer, $
OText: oText, $
OFont: oFont, $
resetTransform:resetTransform}
end
;----------------------------------------------------------------------
;
; PURPOSE This is the main widget definition
; routine used in the Globe demo.
; It constructs a widget and object
; hierarchy which can be used to
; manipulate some images.
;
pro D_Globe, $
GROUP=group, $ ;IN: (opt) group identifier
APPTLB=apptlb ;OUT: (opt) TLB of this application
; Check the validity of the group identifier.
;
ngroup=N_ELEMENTS(group)
if (ngroup NE 0) then begin
check=WIDGET_INFO(group, /VALID_ID)
if (check NE 1) then begin
print,'Error, the group identifier is not valid'
print, 'Return to the main application'
RETURN
endif
groupBase = group
endif else groupBase = 0L
; Get the current color table.
; It will be restored when exiting.
;
TVLCT, savedR, savedG, savedB, /GET
colorTable=[[savedR],[savedG],[savedB]]
; Get the screen size.
;
DEVICE, GET_SCREEN_SIZE = screenSize
; Declare filenames used with the globe demo.
;
fileNameElev=FILEPATH('worldelv.dat', $
SUBDIR=['examples','data'])
fileNameTemp=FILEPATH('worldtmp.gif', $
SUBDIR=['examples','demo','demodata'])
fileNameTips=FILEPATH('globe.tip', $
SUBDIR=['examples','demo','demotext'])
fileNameAbout=FILEPATH('globe.txt', $
SUBDIR=['examples','demo','demotext'])
; Get the tips.
;
sText=getTips(fileNameTips)
nWidgets=2
wText=LONARR(nWidgets)
; Read image datasets. GlobeReadImages returns two pointers to the
; respective images. Each image contains two datasets, whereby
; each dataset is scaled using half of the colors specified
; in calling GlobeReadImages.
;
nColors=190
GlobeReadImages, fileNameElev, fileNameTemp, nColors, $
pImageTemp, pImageTopo, pImageTempTopo, pImageTopoTemp, $
reds, greens, blues
; Construct all base widgets.
;
if (N_ELEMENTS(group) EQ 0) then begin
wTopBase=WIDGET_BASE(TITLE='Globe Demo', $
XPAD=0, YPAD=0, $
/TLB_KILL_REQUEST_EVENTS, $
/COLUMN, TLB_FRAME_ATTR=1, MBAR=barBase)
endif else begin
wTopBase=WIDGET_BASE(TITLE='Globe Demo', $
XPAD=0, YPAD=0, $
/TLB_KILL_REQUEST_EVENTS, $
GROUP_LEADER=group, $
/COLUMN, TLB_FRAME_ATTR=1, MBAR=barBase)
endelse
; Create the buttons in the menu bar.
;
wFileButton=WIDGET_BUTTON(barBase, VALUE='File')
wQuitButton=WIDGET_BUTTON(wFileButton, VALUE='Quit', $
UVALUE='QUIT')
wOptionButton=WIDGET_BUTTON(barBase, VALUE='Options')
wResetButton=WIDGET_BUTTON(wOptionButton, $
VALUE='Reset Orientation', UVALUE='RESET')
wHelpButton=WIDGET_BUTTON(barBase, VALUE='About', /HELP)
wAboutButton=WIDGET_BUTTON(wHelpButton, UVALUE='ABOUT', $
VALUE='About the Globe Demo')
; Create the widgets other than the menu bar.
;
wSubBase=WIDGET_BASE(wTopBase, COLUMN=2)
wLeftBase=WIDGET_BASE(wSubBase, /ALIGN_CENTER, /COLUMN)
wLeftBaseSub1=WIDGET_BASE(wLeftBase, $
/ALIGN_CENTER, /COLUMN, /FRAME)
wSelect1=WIDGET_LABEL(wLeftBaseSub1, $
VALUE='Display Over Continents:')
radioOptions=['Temperature', 'Topography']
wGroup1=CW_BGROUP(wLeftBaseSub1, $
radioOptions, SET_VALUE=1, $
/ROW, /RETURN_INDEX, /EXCLUSIVE, $
/NO_RELEASE, UVALUE='RADIO1')
wLeftBaseSub2=WIDGET_BASE(wLeftBase, $
/ALIGN_CENTER, /COLUMN, /FRAME)
wSelect2=WIDGET_LABEL(wLeftBaseSub2, $
VALUE='Display Over Oceans:')
wGroup2=CW_BGROUP(wLeftBaseSub2, $
radioOptions, SET_VALUE=0, $
/ROW, /RETURN_INDEX, /EXCLUSIVE, $
/NO_RELEASE, UVALUE='RADIO2')
wLeftBaseSub3=WIDGET_BASE(wLeftBase, $
/ALIGN_CENTER, /COLUMN, /FRAME)
wslider3=WIDGET_SLIDER(wLeftBaseSub3, $
/SUPPRESS, MINIMUM=nColors/2, $
MAXIMUM=nColors-1, $
VALUE=nColors/2, $
EVENT_PRO='GlobeStretch_Event', $
TITLE='Stretch temperature minimum')
wslider4=WIDGET_SLIDER(wLeftBaseSub3, $
/SUPPRESS, MINIMUM=nColors/2, $
MAXIMUM=nColors-1, $
VALUE=nColors-1, $
EVENT_PRO='GlobeStretch_Event', $
TITLE='Stretch temperature maximum')
wLeftBaseSub4=WIDGET_BASE(wLeftBase, $
/ALIGN_CENTER, /COLUMN, /FRAME)
wslider1=WIDGET_SLIDER(wLeftBaseSub4, $
/SUPPRESS, MINIMUM=0, $
MAXIMUM=nColors/2-1, VALUE=0, $
EVENT_PRO='GlobeStretch_Event', $
TITLE='Stretch topography minimum ')
wslider2=WIDGET_SLIDER(wLeftBaseSub4, $
/SUPPRESS, MINIMUM=0, $
MAXIMUM=nColors/2-1, VALUE=nColors/2-1, $
EVENT_PRO='GlobeStretch_Event', $
TITLE='Stretch topography maximum ')
wRightBase=WIDGET_BASE(wSubBase, /ALIGN_CENTER, /COLUMN)
wDraw=WIDGET_DRAW(wRightBase, XSIZE=screenSize[0]*.48, $
YSIZE=ScreenSize[0]*.48, $ ;keep isotropic
UVALUE='DRAW', /BUTTON_EVENTS, $
GRAPHICS_LEVEL=2, RETAIN=0, /EXPOSE_EVENTS)
wStatusBase=WIDGET_BASE(wTopBase, /ROW, MAP=0)
nWidgets=2
wText=LONARR(nWidgets)
widTips, wStatusBase, sText.text, wText, NWIDGETS=nWidgets
; Realize the widget hierarchy.
;
WIDGET_CONTROL, wTopBase, /REALIZE
WIDGET_CONTROL, HOURGLASS=1
WIDGET_CONTROL, wDraw, GET_VALUE=oWindow
; Set the user values of each slider to the ids of all sliders because
; these will be needed in the event handler to avoid cases whereby
; minimum sliders are set to values larger than maximum sliders and
; vice versa.
;
wsliders=[wslider1, wslider2, wslider3, wslider4]
; Set the initial value of the sliders.
;
WIDGET_CONTROL, wslider1, SET_UVALUE=wsliders
WIDGET_CONTROL, wslider2, SET_UVALUE=wsliders
WIDGET_CONTROL, wslider3, SET_UVALUE=wsliders
WIDGET_CONTROL, wslider4, SET_UVALUE=wsliders
; Size and map the tips.
;
sizeTips, wTopBase, wText, wStatusBase
WIDGET_CONTROL, wStatusBase, MAP=1
; Create the objects.
; Make the continent-topo & ocean-temperature
; the default view.
;
sObject=GlobeMakeObjects(reds, greens, blues, screenSize, $
pImageTopoTemp, oWindow)
; Build sState structure used in event handlers.
;
sState={$
wGroup1:wGroup1, $ ; Widget Id radio buttons
wGroup2:wGroup2, $ ; Widget Id radio buttons
wDraw:wDraw, $ ; Widget draw ID
oImage:sObject.oImage, $ ; Image object
oSphere:sObject.oSphere, $ ; Sphere object
oTrack:sObject.oTrack, $ ; Trackball object
oModelTranslate:sObject.oModelTranslate, $ ; Models
oModelRotate:sObject.oModelRotate, $
oModelScale:sObject.oModelScale, $
OContainer: sObject.oContainer, $ ; Container object
oWindow:sObject.oWindow, $ ; Widnow object
oView:sObject.oView, $ ; View object
oFont:sObject.oFont, $ ; Font object
oText:sObject.oText, $ ; Text object
oPalette:sObject.oPalette, $ ; Color palette object
resetTransform:sObject.resetTransform, $ ; Transformation matrix to reset
pImageTemp:pImageTemp, $ ; Pointers to images
pImageTopo:pImageTopo, $
pImageTempTopo:pImageTempTopo, $
pImageTopoTemp:pImageTopoTemp, $
nColors:nColors, $ ; Number of available colors
reds:reds, $ ; RGB color arrays
greens:greens, $
blues:blues, $
colorTable:colorTable, $ ; Color table to restore
fileNameAbout:fileNameAbout, $
groupBase: groupBase $ ; Base of Group Leader
}
WIDGET_CONTROL, wTopBase, SET_UVALUE=sState, /NO_COPY
WIDGET_CONTROL, HOURGLASS=0
; Remove the starting up text.
;
sObject.oModelTranslate->Remove, sObject.oText
; Returns the top level base to the APPTLB keyword.
;
appTLB=wTopBase
; Modify the initial setting of the sliders. First create
; a pseudo event structure, then call the globeStretch_Event
; routine with the pseudo structure, then set the slider
; to the desired value
;
; Stretching the temperature minimum slider at 30% of
; its range and rotate the globe.
;
sObject.oModelRotate->Rotate, [0, 1, 0], -20.0
sObject.oModelRotate->Rotate, [1, 0, 0], 10.0
deltaTempMin = (nColors-1 - nColors/2 ) * 0.3
increment = (deltaTempMin) / 2
for i = 0, deltaTempMin, increment do begin
sObject.oModelRotate->Rotate, [0, 1, 0], -5
sObject.oModelRotate->Rotate, [1, 0, 0], 2.5
newValue = nColors/2 + i
pseudoEvent = { $
ID : wslider3, $
TOP: wTopBase, $
HANDLER: wslider3, $
VALUE: newValue, $
DRAG: 0 $
}
WIDGET_CONTROL, wslider3, SET_VALUE=newValue
globeStretch_Event, pseudoEvent
endfor
; Stretching the temperature maximum slider at 85% of
; its range and rotate the globe.
;
deltaTempMax = (nColors-1 - nColors/2)*0.15
increment = (deltaTempMax) / 3
for i = 0, deltaTempMax, increment do begin
sObject.oModelRotate->Rotate, [0, 1, 0], -5
sObject.oModelRotate->Rotate, [1, 0, 0], 2.5
newValue = (nColors-1) - i
pseudoEvent = { $
ID : wslider4, $
TOP: wTopBase, $
HANDLER: wslider4, $
VALUE: newValue, $
DRAG: 0 $
}
WIDGET_CONTROL, wslider4, SET_VALUE=newValue
globeStretch_Event, pseudoEvent
endfor
; Stretching the topography maximum slider at 35% of
; its range.
;
deltaTempMax = nColors/2 - 1
newValue = (nColors/2 - 1) * 0.35
pseudoEvent = { $
ID : wslider2, $
TOP: wTopBase, $
HANDLER: wslider2, $
VALUE: newValue, $
DRAG: 0 $
}
WIDGET_CONTROL, wslider2, SET_VALUE=newValue
globeStretch_Event, pseudoEvent
; Register with the XMANAGER
;
XMANAGER, 'd_Globe', wTopBase, /NO_BLOCK, $
EVENT_HANDLER='d_Globe_Event', CLEANUP="d_GlobeCleanup"
end